package com.qq.spirit;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;

import com.qq.spirit.inter.IActionAfterHttpRequest;
import com.qq.spirit.model.UserData;

/**
 * 封装的http请求对象
 * 
 * @author Administrator
 * 
 */
public class HttpUtil
{

	public static void doPost(int gid, String url, List<BasicNameValuePair> pList, IActionAfterHttpRequest afterReqest)
	{
		doPost(gid, url, pList, new DefaultRedirectStrategy(), afterReqest);
	}

	/**
	 * 执行post请求
	 * 
	 * @param session
	 * @param url
	 * @param pList
	 * @return
	 */
	public static void doPost(int gid, String url, List<BasicNameValuePair> pList, RedirectStrategy redirectStrategy, IActionAfterHttpRequest afterReqest)
	{
		DefaultHttpClient httpclient = HttpClientUnit.getDefaultHttpClient(gid);
		String content = "";
		List<Header> headList = new ArrayList<Header>();
		String contenttype = "";
		HttpPost wr = new HttpPost(url);
		try
		{
			httpclient.setRedirectStrategy(redirectStrategy);
			setParam(wr);
			wr.setHeader("Cookie", getCookieStr(gid));
			wr.setEntity(new UrlEncodedFormEntity(pList, "UTF-8"));
			HttpResponse response = httpclient.execute(wr);
			getHeaderList(response,headList);
			contenttype = getResponseCodingType(response);
			content = decodeResponseContent(response.getEntity().getContent(), contenttype, "utf-8");
		} catch (Exception e)
		{
			// LoggerUtil.error(e);
		} finally
		{
			wr.abort();
			if (afterReqest != null)
			{
				afterReqest.call(contenttype, headList, content);
			}
		}
	}

	private static String getCookieStr(int gid)
	{
		UserData u = GameUserInfoUtil.getUser(gid);
		Iterator<String> ite = u.getCookieKey();
		StringBuffer sB = new StringBuffer();
		boolean isF = true;
		while (ite.hasNext())
		{
			String k = ite.next();
			String v = u.getCookie(k);
			if (!isF)
			{
				sB.append("; ");
			} else
			{
				isF = false;
			}
			sB.append(k).append("=").append(v);
		}

		return sB.toString();
	}

	public static void setParam(HttpRequestBase h)
	{
		// h.setHeader("x-flash-version", "11,2,202,228");
		// h.setHeader("Content-Type", "application/x-www-form-urlencoded");
		h.setHeader("Accept-Encoding", "gzip, deflate");
		h.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0");
		// h.setHeader("Host", "http://www.as.yaowan.com");
		h.setHeader("Proxy-Connection", "Keep-Alive");
		h.setHeader("Accept-Language", "zh-CN");
		h.setHeader("Accept", "*/*");
	}

	/**
	 * 发送get请求
	 * 
	 * @param name
	 *            请求的号码
	 * @param url
	 *            请求的url
	 */
	public static void doGet(int gid, String url, IActionAfterHttpRequest afterReqest)
	{
		doGet(gid, url, new DefaultRedirectStrategy(), afterReqest);
	}

	/**
	 * 发送get请求
	 * 
	 * @param name
	 *            请求的号码
	 * @param url
	 *            请求的url
	 */
	public static void doGet(int gid, String url, RedirectStrategy redirectStrategy, IActionAfterHttpRequest afterReqest)
	{
		DefaultHttpClient httpclient = HttpClientUnit.getDefaultHttpClient(gid);
		String content = "";
		List<Header> headList = new ArrayList<Header>();
		String contenttype = "";
		HttpGet p = new HttpGet(url);
		try
		{
			httpclient.setRedirectStrategy(redirectStrategy);
			setParam(p);
			p.setHeader("Cookie", getCookieStr(gid));
//			p.setHeader("Cookie", "JSESSIONID=6565B61995A4C06D28A3D55182E746A4, userid=6906579, PHPSESSID=de6308e2e740652b31720bd5f03784fc, usersign=d718faf4f7f81da5f9143bb8d8d8450e");
			HttpResponse response = httpclient.execute(p);
			getHeaderList(response,headList);
			contenttype = getResponseCodingType(response);
			content = decodeResponse(response);
		} catch (Exception e)
		{
			LoggerUtil.error(gid, e);
		} finally
		{
			p.abort();
			if (afterReqest != null)
			{
				afterReqest.call(contenttype, headList, content);
			}
		}
	}

	public static void getHeaderList(HttpResponse response,List<Header> headList)
	{
		Header[] h = response.getAllHeaders();
		if (h != null)
		{
			for (int i = 0; i < h.length; i++)
			{
				headList.add(h[i]);
			}
		}
	}
	/**
	 * 获得值
	 * 
	 * @param p
	 * @param name
	 * @return
	 */
	private static String getHeaderValue(HttpResponse p, String name)
	{
		Header h = p.getFirstHeader(name);
		if (h == null)
		{
			return "";
		} else
		{
			return h.getValue();
		}
	}

	/**
	 * 获取请求结果的编码类型
	 * 
	 * @param p
	 * @return
	 */
	public static String getResponseCodingType(HttpResponse p)
	{
		String ceValue = getHeaderValue(p, "Content-Encoding");
		if (ceValue.indexOf("gzip") >= 0)
		{
			return "gzip";
		}
		String ctValue = getHeaderValue(p, "Content-Type");
		if (ctValue.indexOf("x-gzip-compressed") >= 0)
		{
			return "zlib";
		}
		return "html";
	}

	/**
	 * 解析输出流
	 * 
	 * @param response
	 * @return
	 */
	public static String decodeResponse(HttpResponse response) throws Exception
	{
		return decodeResponseContent(response.getEntity().getContent(), getResponseCodingType(response), "utf-8");
	}

	/**
	 * 解析输入类型
	 * 
	 * @param ins
	 * @param codingType
	 * @param charSet
	 * @return
	 */
	public static String decodeResponseContent(InputStream ins, String codingType, String charSet) throws Exception
	{
		if (codingType.endsWith("gzip"))
		{
			return decodeGzip(ins, charSet);
		}
		if (codingType.endsWith("zlib"))
		{
			return decodeZlib(ins, charSet);
		}
		if (codingType.endsWith("html"))
		{
			return decodeText(ins, charSet);
		}

		return decodeText(ins, charSet);
	}

	/**
	 * 解析普通的未经压缩的输入流
	 * 
	 * @param ins
	 * @param charsetName
	 * @return
	 */
	private static String decodeText(InputStream ins, String charsetName) throws Exception
	{
		byte[] ib = new byte[1024];
		ByteArrayOutputStream oBuff = new ByteArrayOutputStream();
		int tlen = -1;
		while ((tlen = ins.read(ib)) != -1)
		{
			oBuff.write(ib, 0, tlen);
		}
		return new String(oBuff.toByteArray(), charsetName);
	}

	/**
	 * 解码gzip类型编码,默认均为utf-8编码
	 * 
	 * @param ins
	 * @return
	 */
	private static String decodeZlib(InputStream ins, String charsetName) throws Exception
	{
		ByteArrayOutputStream oBuff;
		InflaterInputStream gis = new InflaterInputStream(ins);
		byte[] ib = new byte[1024];
		oBuff = new ByteArrayOutputStream();
		int tlen = -1;
		// 放弃前2个直接，这2个不知道干啥的，可能是标志
		// zis.read(ib,0, 2);
		while ((tlen = gis.read(ib)) != -1)
		{
			oBuff.write(ib, 0, tlen);
		}
		return new String(oBuff.toByteArray(), charsetName);
	}

	/**
	 * 解码gzip类型编码,默认均为utf-8编码
	 * 
	 * @param ins
	 * @return
	 */
	private static String decodeGzip(InputStream ins, String charsetName) throws Exception
	{
		GZIPInputStream gis = new GZIPInputStream(ins);
		byte[] ib = new byte[1024];
		ByteArrayOutputStream oBuff = new ByteArrayOutputStream();
		int tlen = -1;
		while ((tlen = gis.read(ib)) != -1)
		{
			oBuff.write(ib, 0, tlen);
		}
		return new String(oBuff.toByteArray(), charsetName);
	}
}
